﻿// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "pch.h"
#include <Windows.h>
#include "tools.h"
#include <stdio.h>
#include <string>
EXTERN_C VOID TestAsm();


typedef int (__fastcall* RtlInsertInvertedFunctionTableProc)( PVOID BaseAddress, ULONG sizeofImage);


VOID DealException32(HMODULE hModule) {
       HMODULE hntdll = GetModuleHandleA("ntdll.dll");
    PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)hntdll;
    PIMAGE_NT_HEADERS pNts = (PIMAGE_NT_HEADERS)((PUCHAR)hntdll + pDos->e_lfanew);


    PIMAGE_DOS_HEADER pMyDos = (PIMAGE_DOS_HEADER)hModule;
    PIMAGE_NT_HEADERS pMyNts = (PIMAGE_NT_HEADERS)((PUCHAR)hModule + pMyDos->e_lfanew);
    ULONG sizeofImage = pMyNts->OptionalHeader.SizeOfImage;
    FindCode fs[1];
    initFindCodeStruct(&fs[0], (char*)"8B70*8BD68B8D****E8****", 0, 0);
    ULONG addr = findAddressByCode((ULONG)hntdll + pNts->OptionalHeader.BaseOfCode, (ULONG)hntdll + pNts->OptionalHeader.BaseOfCode + pNts->OptionalHeader.SizeOfCode, fs, 1);
    RtlInsertInvertedFunctionTableProc RtlInsertInvertedFunctionTable = (RtlInsertInvertedFunctionTableProc)GetFunctionAddressByCodeAddress(addr + 11);

    char buf[245] = { 0 };
    sprintf_s(buf, "%x\r\n", RtlInsertInvertedFunctionTable);

    MessageBoxA(NULL, buf, NULL, NULL);
    RtlInsertInvertedFunctionTable(hModule, sizeofImage);
}


VOID DealException64(HMODULE hModule)
{
    PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)hModule;
    PIMAGE_NT_HEADERS pNts = (PIMAGE_NT_HEADERS)((PUCHAR)hModule + pDos->e_lfanew);

    IMAGE_DATA_DIRECTORY pExceptionDir = (IMAGE_DATA_DIRECTORY)pNts->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXCEPTION];

    PRUNTIME_FUNCTION pRunTimeFunc = (PRUNTIME_FUNCTION)((PUCHAR)hModule + pExceptionDir.VirtualAddress);
    int count = pExceptionDir.Size / sizeof(RUNTIME_FUNCTION);
    RtlAddFunctionTable(pRunTimeFunc, count, (ULONG_PTR)hModule);
    /*
     for (int i = 0; i < count; i++) {
         RUNTIME_FUNCTION temp = pRunTimeFunc[i];
         printf("b = %x e = %x sInfo = %x\r\n", temp.BeginAddress,temp.EndAddress,temp.UnwindData);
     }*/
}

PRUNTIME_FUNCTION
Runtime_Fun_Callback(
    _In_ DWORD64 ControlPc,//发生异常的位置
    _In_opt_ PVOID Context//moduleBase
) {
    PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)Context;
    PIMAGE_NT_HEADERS pNts = (PIMAGE_NT_HEADERS)((PUCHAR)Context + pDos->e_lfanew);
    IMAGE_DATA_DIRECTORY pExceptionDir = (IMAGE_DATA_DIRECTORY)pNts->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXCEPTION];

    PRUNTIME_FUNCTION pRunTimeFunc = (PRUNTIME_FUNCTION)((PUCHAR)Context + pExceptionDir.VirtualAddress);
    int count = pExceptionDir.Size / sizeof(RUNTIME_FUNCTION);
    PRUNTIME_FUNCTION find = NULL;
    for (int i = 0; i < count; i++) {
        RUNTIME_FUNCTION temp = pRunTimeFunc[i];
        if (ControlPc >= temp.BeginAddress && ControlPc <= temp.EndAddress) {
            find = &pRunTimeFunc[i];
           
            break;
        }
    }
   
    return find;
}
VOID AddException64(HMODULE hModule) {

    PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)hModule;
    PIMAGE_NT_HEADERS pNts = (PIMAGE_NT_HEADERS)((PUCHAR)hModule + pDos->e_lfanew);

    ULONG64 hmodulexx = (ULONG64)hModule | 0x3;
    RtlInstallFunctionTableCallback(hmodulexx,
        (ULONG_PTR)hModule, pNts->OptionalHeader.SizeOfImage,
        Runtime_Fun_Callback,
        hModule, NULL
    );

}

const char* filePath = "C:\\1.txt";
BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
    {
        AddException64( hModule);


        MessageBoxA(NULL, NULL, NULL, NULL);

       
    __try {

        int x = 0;
        int y = x / x;


    }
    __except (1) {

        MessageBoxA(NULL, NULL, NULL, NULL);
    }
    }



        
       
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}

